const puppeteer = require('puppeteer')
const fs = require('fs')
const chalk = require('chalk')
const path = require('path')
const JSON2Excel = require('./JSON2Excel')
const keywords = require('./keywords')

function sleep(timeout) {
  return new Promise(resolve => setTimeout(resolve, timeout))
}

function initSearch(page, keyword) {
  return new Promise(async resolve => {
    await page.$eval('input#sole-input', (el, _keyword) => {
      el.value = _keyword
    }, keyword)
    await sleep(2000)
    // 点击两次搜索按钮，不然可能会有问题，第一页数据可能爬不到
    await page.click('button#search-button')
    await sleep(5000)

    await page.click('button#search-button')
    await sleep(5000)
    resolve()
  })
}


function getCurrentPageData(page) {
  return new Promise(async resolve => {
    const currentPageData = await page.$$eval('ul.poilist .search-item.base-item', (DOMList) => {
      DOMList = Array.from(DOMList)
      return DOMList.map(DOMItem => {
        var titleEle = DOMItem.querySelector('a[data-stat-code="poisearch.all.title"]')
        var addressEle = DOMItem.querySelector('.row.addr .n-grey')
        var phoneEle = DOMItem.querySelector('.row.tel')
        var imgEle = DOMItem.querySelector('a[data-stat-code="poisearch.all.image"] img')
        var img = '暂无图片'
        if (imgEle) {
          // 爬到的图片太小了，放大十倍
          img = imgEle.src.replace(/width=\d+|height=\d+/g, v => v + '0')
        }
        return {
          ['商户名称']: titleEle.innerText,
          ['商户地址']: addressEle.innerText,
          ['手机号码']: phoneEle ? phoneEle.innerText : '暂无电话',
          ['店铺照']: img
        }
      })
    })

    resolve(currentPageData)
  })
}

async function hasMore(page) {
  return new Promise(resolve => {
    page.$eval('a[tid="toNextPage"]', el => {
      if (!el) {
        return false
      } else {
        return !el.classList.contains('next-none')
      }
    }).then(resolve).catch(() => { resolve(false) })
  })
}

function getKeywordData(page, keyword){
  console.log(chalk.yellow('开始爬取\"' + keyword + '\"数据'));
  return new Promise(async resolve => {
    const dataCollection = []
    let forceQuitFlag = 0
    while (1) {
      forceQuitFlag++
      const pageData = await getCurrentPageData(page)
      dataCollection.push(...pageData)
      fs.writeFileSync(path.join(__dirname, './json/', keyword + '.json'), JSON.stringify(dataCollection))
      console.log(chalk.green('本页数据写入完毕'))
      await sleep(2000)
      var hasMoreData = await hasMore(page)
      if (hasMoreData) {
        if (forceQuitFlag <= 15) {
  
          await page.click('a[tid="toNextPage"]')
          console.log(chalk.blue('休息5秒后继续...'))
          await sleep(5000)
        } else {
  
          console.log(chalk.blue('爬取完毕，正在将数据转换为Excel格式'))
          JSON2Excel(path.join(__dirname, './json/', keyword + '.json'))
  
          console.log(chalk.blue('转换完毕'))
          resolve()
          break
        }
      } else {
  
        console.log(chalk.blue('爬取完毕，正在将数据转换为Excel格式'))
        JSON2Excel(path.join(__dirname, './json/', keyword + '.json'))
  
        console.log(chalk.blue('转换完毕'))
        resolve()
        break
      }
    }
  })
}


; !async function () {
  const browser = await puppeteer.launch({ headless: false, defaultViewport: { width: 1280, height: 960 } });
  const page = await browser.newPage();
  
  await page.goto('https://map.baidu.com/')
  
  await page.waitForSelector('input#sole-input')


  for(let keyword of keywords) {
    if(!fs.existsSync( path.join(__dirname, './json/', keyword + '.json') )) {
      await initSearch(page, keyword)
      await sleep(3000)
      await getKeywordData(page, keyword)
    }
  }

  
  console.log(chalk.blueBright('所有关键字爬取完毕'));
  console.log(chalk.blueBright('正在对数据进行清洗'));

  require('./clearData')

  console.log(chalk.blueBright('程序退出'));
 
  process.exit(0)
}()